#pragma once
#ifndef _MAINWINDOW_H_
#define _MAINWINDOW_H_
#ifdef WIN32
#pragma execution_character_set("utf-8")
#endif

#include <QApplication>
#include <QMainWindow>
#include<QWidget>
#include<qcombobox.h>
#include <QDebug>
#include <QtConcurrent/QtConcurrentRun>
#include <QFile>
#include <QShortcut>
#include "form/ui_MainWindow.h"
#include "appService.h"
#include "timeUtils.h"
#include "MyError.h"
#include "utils.h"
#include "dialogs.h"
#include"PrinterManager.h"

#include <QVTKOpenGLNativeWidget.h>           //窗口显示使用
#include <pcl/visualization/pcl_visualizer.h>
#include <vtkGenericOpenGLRenderWindow.h>

#include <pcl/io/pcd_io.h>                    //pcd文件读取写入使用
#include <pcl/point_types.h>            //法线信息
#include <pcl/point_cloud.h>            //pcd文件使用
#include<pcl/common/transforms.h> //点云变换
class MainWindow : public QMainWindow {

    Q_OBJECT

public:

    MainWindow();

    ~MainWindow();

    void init();

    void initUI();

    void initialVtkWidget();

    void showTestResult(QTableWidget* table, staticalParameters data);

    //添加参数
    void addTestParams(QString paramType, QString name);


    //查询检测参数
    void queryTestParams();


    /// <summary>
    /// 生成表格项并居中显示
    /// </summary>
    /// <param name="table">要添加数据的表格</param>
    /// <param name="row">目标行</param>
    /// <param name="col">目标列</param>
    /// <param name="val">要添加的数据</param>
    /// <param name="decimal">当填充的是小数时，保留的小数位数</param>
    /// <param name="alignment">对其方式</param>
    void insertValue2Table(QTableWidget* table, int row, int col, QVariant val, int decimal = 2, int alignment = Qt::AlignCenter);

protected:

    /// <summary>
    /// 查询指定日期的测试几率
    /// </summary>
    /// <param name="beginDay">开始日期</param>
    /// <param name="endDay">截止日期</param>
    /// <param name="tester">测试员</param>
    /// <param name="schedule">班次</param>
    void queryTestRecord(QDate& beginDay, QDate& endDay, QString tester = "", QString schedule = "");

private:

    /// <summary>
    /// 按钮/表格被点击时的处理函数，防止按钮重复点击
    /// </summary>
    /// <param name="btnFunction"></param>
    void objClicked(std::function<void()> objFunction, int timeout = 100);

    /// <summary>
    /// 重置电运动电机的参数
    /// </summary>
    void resetMotoParams();

    /// <summary>
    /// 重置相机参数 
    /// </summary>
    void resetCameraParams();

    /// <summary>
    /// 校验检测参数
    /// </summary>
    /// <returns></returns>
    bool checkTestParams(DaoModel::TestData& data);

    /// <summary>
    /// 菜单按钮被点击的处理函数
    /// </summary>
    /// <param name="btnClicked">按钮事件</param>
    void menuBtnClicked(std::function<int()> btnClicked);

    /// <summary>
    /// 检测完成之后的处理函数
    /// </summary>
    void testFinishedHandle();

    //查询检测中的牌号，班次以及检测员等信息
    void queryHistoryTestParams();

protected slots:

    // 接收点云数据
    void processCloudData(pcl::PointCloud<pcl::PointXYZ>::Ptr& data,staticalParameters cloudStaticalData);


    //// 测试按钮
    //void on_testBtn_clicked();

    //检测完成，显示检测结果
    void onTestFinished(MyModel::TestData& data, const MyError& error);

    //退出按钮
    void on_exitBtn_clicked();

    //返回主页按钮
    void on_homeBtn_clicked();

    //关机按钮
    void on_shutdownBtn_clicked();

    //标定按钮
    void on_demarcateBtn_clicked();

    //设置按钮
    void on_settingBtn_clicked();

    //开发者模式按钮
    void on_developBtn_clicked();

    //检测按钮
    void on_measureBtn_clicked();

    //查询按钮
    void on_queryBtn_clicked();

    //关于按钮
    void on_aboutBtn_clicked();

    //开始测量按钮
    void on_startTestBtn_clicked();

    //重置参数按钮
    void on_resetParamsBtn_clicked();

    //打印测量结果按钮
    void on_printTestDataBtn_clicked();

    //导出测量结果按钮
    void on_exportTestDataBtn_clicked();

    //删除测量结果按钮
    void on_deleteTestDataBtn_clicked();

    //清空测量结果按钮
    void on_clearTestDataBtn_clicked();

    //电机参数确认并下发
    void on_confirmMotoParamsSettingBtn_clicked();

    //电机参数保存
    void on_saveMotoParamsSettingBtn_clicked();

    //重置电机参数
    void on_resetMotoParamsSettingBtn_clicked();

    //点击返回
    void on_motoBackBtn_clicked();

    //扫描测试
    void on_motoScannerTestBtn_clicked();

    //停止移动
    void on_stopMotoMoveBtn_clicked();

    //确认相机参数
    void on_confrimCameraSettingBtn_clicked();

    //重置相机参数
    void on_resetCameraSettingBtn_clicked();

    //伺服控制转动
    void on_servoTestBtn_clicked();

    //伺服反转➡️停止
    void on_stopServoRotateBtn_clicked();

    //主轮控制
    void on_DrivenWheelControlBtn_2_clicked();

    //从轮控制
    void on_FollowedWheelControlBtn_2_clicked();

    //=====================查询页面=====================//
    //查询记录
    void on_qConfirmBtn_clicked();

    //重置查询条件
    void on_qResetBtn_clicked();

    //导出查询结果
    void on_qExportBtn_clicked();

    //打印查询结果
    void on_qPrintBtn_clicked();

    //删除单个记录数据
    void on_qDeleteBtn_clicked();

    //当历史检测记录表格上的行被点击时，查询当前记录
    void on_qResultTable_cellClicked(int row, int column);

    //=======================测量界面按钮============================//


private:

    Ui::MainWindow* m_ui;

    //显示开发者菜单的快捷键
    QShortcut* m_devShortcut = nullptr;

    // 应用控制程序
    AppService m_app;

    //显示图像的标签
    QLabel* m_liveLabel = nullptr;

    //检测记录
    MyModel::TestRecord m_testRecord;

    //检测时间
    QDateTime m_testTime;

    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer;

    DaoModel::TestData m_testData;  //当前批次的检测数据

    QList<DaoModel::TestData> m_testDataList;//当前检测批次的额数据列表

    QList<DaoModel::TestData>m_queryData;    //查询到的数据列表

    /*---------------- 表格默认行 --------------------*/

    int m_testTableMinRow = 10;         //测量结果表格最少的行数

    int m_historyTableMinRow = 0;      //历史记录表默认行数

    int m_historyDataTableMinRow = 0;  //历史记录表默认行数

    int m_brandTableMinRow = 0;        //牌号信息表格默认行数

    int m_testerTableMinRow = 0;       //检测员信息表格默认行数

    int m_scheduleTableMinRow = 0;     //班次表格默认行数
};
#endif